package com.frame.util.tool.image;

import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.Rectangle;
import java.awt.RenderingHints;
import java.awt.image.BufferedImage;
import java.awt.image.ConvolveOp;
import java.awt.image.Kernel;
import java.io.*;
import javax.imageio.ImageIO;
import com.sun.image.codec.jpeg.JPEGCodec;
import com.sun.image.codec.jpeg.JPEGEncodeParam;
import com.sun.image.codec.jpeg.JPEGImageEncoder;

/**
 *
 * 功能:图像操作<br>
 * 参数:<br>
 * 作者:王海锋<br>
 * 时间:2017-1-13上午11:02:51<br>
 */
public class ImageUtil {

	public static void main(String[] ss){
		File destFile = new File("f:\\IMG_20150215_121531.jpg");
		FileInputStream in=null;
		FileOutputStream out=null;
		try{
			in=new FileInputStream(destFile);
			out=new FileOutputStream(new File("f:\\b.jpg"));
			new ImageUtil().resizeByWidth(in, 200, out);
		}catch(Exception e){e.printStackTrace();}finally{
			try {
				out.close();
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			try {
				out.close();
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
	}

	/**
	 * 以宽度为基准，等比例放缩图片
	 * @param w int 新宽度
	 * @throws Exception
	 */
	public void resizeByWidth(InputStream in,int w,OutputStream out) throws Exception {
		Image img=ImageIO.read(in);
		int width = img.getWidth(null);
		int height = img.getHeight(null);
		int resizew=w;
		int resizeh = (int) (height * w / width);
		if(w>=width){resizew=width;resizeh=height;}
		resize(img,resizew,resizeh,out);
	}

	public void resize(Image img,int w,int h,OutputStream out) throws Exception{
		BufferedImage image = new BufferedImage(w, h,BufferedImage.TYPE_INT_RGB );
		image.getGraphics().drawImage(img, 0, 0, w, h, null);
		JPEGImageEncoder encoder = JPEGCodec.createJPEGEncoder(out);
		encoder.encode(image);
	}

	public void resize(InputStream in,int w,int h,OutputStream out) throws Exception{
		Image img=ImageIO.read(in);
		BufferedImage image = new BufferedImage(w, h,BufferedImage.TYPE_INT_RGB );
		image.getGraphics().drawImage(img, 0, 0, w, h, null); // 绘制缩小后的图
		// 可以正常实现bmp、png、gif转jpg
		JPEGImageEncoder encoder = JPEGCodec.createJPEGEncoder(out);
		encoder.encode(image); // JPEG编码
	}
	public BufferedImage rotateImage(BufferedImage image,int angel) {
		int src_width = image.getWidth(null);
		int src_height = image.getHeight(null);
		// calculate the new image size
		Rectangle rect_des = CalcRotatedSize(new Rectangle(new Dimension(
				src_width, src_height)), angel);

		BufferedImage res = null;
		res = new BufferedImage(rect_des.width, rect_des.height,
				BufferedImage.TYPE_INT_RGB);
		Graphics2D g2 = res.createGraphics();
		// transform
		g2.translate((rect_des.width - src_width) / 2,
				(rect_des.height - src_height) / 2);
		g2.rotate(Math.toRadians(angel), src_width / 2, src_height / 2);

		g2.drawImage(image, null, null);
		return res;
	}


	public void cut(Double x,Double y,Double w,Double h,InputStream in,OutputStream out,String type) throws IOException{
		try{
			BufferedImage sourceImg =ImageIO.read(in);
			int srcW=sourceImg.getWidth();
			int srcH=sourceImg.getHeight();
			int l=x.intValue();
			int t=y.intValue();
			int sizew=w.intValue();
			int sizeh=h.intValue();
			if(l<0){sizew=sizew+l;l=0;}
			if(t<0){sizeh=sizeh+t;t=0;}
			if((l+sizew)>srcW){sizew=srcW-l;}
			if((t+sizeh)>srcH){sizeh=srcH-t;}
			BufferedImage subImage = sourceImg.getSubimage(l,t, sizew,sizeh);
			ImageIO.write(subImage,type.toUpperCase(),out);
		}finally{
			if(in!=null)in.close();
		}
	}

	public void cutAndResize(Double startx,Double starty,Double w,Double h,int resizew,int resizeh,InputStream in,OutputStream out) throws IOException{
		BufferedImage sourceImg =ImageIO.read(in);
		cutAndResize(startx, starty, w, h, resizew, resizeh, sourceImg, out);
	}
	public void cutAndResize(Double startx,Double starty,Double w,Double h,int resizew,int resizeh,BufferedImage sourceImg,OutputStream out) throws IOException{
		try{
			int srcW=sourceImg.getWidth();
			int srcH=sourceImg.getHeight();
			int l=startx.intValue();
			int t=starty.intValue();
			int sizew=w.intValue();
			int sizeh=h.intValue();
			if(l<0){sizew=sizew+l;l=0;}
			if(t<0){sizeh=sizeh+t;t=0;}
			if((l+sizew)>srcW){sizew=srcW-l;}
			if((t+sizeh)>srcH){sizeh=srcH-t;}
			BufferedImage subImage = sourceImg.getSubimage(l,t, sizew,sizeh);
			BufferedImage zoomImage = new BufferedImage(resizew, resizeh,BufferedImage.TYPE_INT_RGB);
			Image image = subImage.getScaledInstance(resizew, resizeh,Image.SCALE_SMOOTH);
			zoomImage.getGraphics().drawImage(image, 0, 0, null);

			Graphics g=zoomImage.getGraphics();
			g.setColor(Color.white);
			g.fillRect(0, 0, resizew, resizeh);
			g.drawImage(image, 0, 0, null);
			g.dispose();
			float softenFactor = 0.05f;
			float[] softenArray = { 0, softenFactor, 0, softenFactor,
					1 - (softenFactor * 4), softenFactor, 0, softenFactor, 0 };
			Kernel kernel = new Kernel(3, 3, softenArray);
			ConvolveOp cOp = new ConvolveOp(kernel, ConvolveOp.EDGE_NO_OP, null);
			zoomImage = cOp.filter(zoomImage, null);
			JPEGImageEncoder encoder = JPEGCodec.createJPEGEncoder(out);
			JPEGEncodeParam param = encoder
					.getDefaultJPEGEncodeParam(zoomImage);
			param.setQuality(1f, true);
			encoder.setJPEGEncodeParam(param);
			encoder.encode(zoomImage);
		}catch(Exception e){e.printStackTrace();}finally{
			try {
				if(out!=null)
					out.close();
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
	}

	private static Rectangle CalcRotatedSize(Rectangle src, int angel) {
		// if angel is greater than 90 degree, we need to do some conversion
		if (angel >= 90) {
			if(angel / 90 % 2 == 1){
				int temp = src.height;
				src.height = src.width;
				src.width = temp;
			}
			angel = angel % 90;
		}

		double r = Math.sqrt(src.height * src.height + src.width * src.width) / 2;
		double len = 2 * Math.sin(Math.toRadians(angel) / 2) * r;
		double angel_alpha = (Math.PI - Math.toRadians(angel)) / 2;
		double angel_dalta_width = Math.atan((double) src.height / src.width);
		double angel_dalta_height = Math.atan((double) src.width / src.height);

		int len_dalta_width = (int) (len * Math.cos(Math.PI - angel_alpha
				- angel_dalta_width));
		int len_dalta_height = (int) (len * Math.cos(Math.PI - angel_alpha
				- angel_dalta_height));
		int des_width = src.width + len_dalta_width * 2;
		int des_height = src.height + len_dalta_height * 2;
		return new java.awt.Rectangle(new Dimension(des_width, des_height));
	}
}
